package com.management.department.teacherinfosystem.Controller;

import com.management.department.teacherinfosystem.Entity.*;
import com.management.department.teacherinfosystem.Repository.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequiredArgsConstructor
public class AcademicSocialController {

    private final UserRepository userRepository;
    private final AcademicPositionRepository positionRepository;
    private final SocialServiceRepository serviceRepository;
    private final AttachmentRepository attachmentRepository;

    @Value("${file.upload.academic-dir:uploads/academic_achievements/}")
    private String academicUploadDir;

    @Value("${file.upload.award-dir:/uploads/awards/}")
    private String fallbackUploadDir;

    /* =================== 公共方法 =================== */

    private User currentUser() {
        org.springframework.security.core.Authentication auth = org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
        String username = auth.getName();
        return userRepository.findByUsernameWithRoles(username).orElse(null);
    }

    private boolean currentIsAdmin() {
        org.springframework.security.core.Authentication auth = org.springframework.security.core.context.SecurityContextHolder.getContext().getAuthentication();
        return auth.getAuthorities().stream().anyMatch(a -> {
            String au = a.getAuthority();
            return "ROLE_ADMIN".equalsIgnoreCase(au) || "ADMIN".equalsIgnoreCase(au);
        });
    }

    private File ensureDir(String base) {
        if (!StringUtils.hasText(base)) base = fallbackUploadDir;
        if (!base.endsWith("/") && !base.endsWith("\\")) base = base + "/";
        File dir = new File(base);
        if (!dir.exists()) dir.mkdirs();
        return dir;
    }

    private <T> List<T> applyPaging(List<T> list, Integer page, Integer size) {
        if (page == null || size == null || page < 1 || size < 1) return list;
        int from = Math.min((page - 1) * size, list.size());
        int to = Math.min(from + size, list.size());
        return list.subList(from, to);
    }

    /* =================== 学术兼职 =================== */

	@GetMapping("/api/academic-positions/mine")
	@Transactional(readOnly = true)
	public ResponseEntity<?> myPositions() {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        List<AcademicPosition> list = positionRepository.findByUser(u);
        return ResponseEntity.ok(list.stream().map(p -> {
            Map<String, Object> m = new LinkedHashMap<>();
            m.put("id", p.getId());
            m.put("positionCategory", p.getPositionCategory());
            m.put("positionTitle", p.getPositionTitle());
            m.put("organizationName", p.getOrganizationName());
            m.put("level", p.getLevel());
            m.put("year", p.getYear());
            m.put("startDate", p.getStartDate());
            m.put("endDate", p.getEndDate());
            m.put("status", p.getStatus());
            return m;
        }).toList());
    }

	@PostMapping("/api/academic-positions")
	@Transactional
	public ResponseEntity<?> createPosition(@RequestBody Map<String, Object> payload) {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        AcademicPosition ap = new AcademicPosition();
        ap.setUser(u);
        ap.setPositionCategory((String) payload.get("position_category"));
        ap.setPositionTitle((String) payload.get("position_title"));
        ap.setOrganizationName((String) payload.get("organization_name"));
        ap.setLevel((String) payload.getOrDefault("level", null));
        ap.setYear(payload.get("year") == null ? null : Integer.valueOf(String.valueOf(payload.get("year"))));
        LocalDate newStart = Optional.ofNullable((String) payload.get("start_date")).map(LocalDate::parse).orElse(null);
        LocalDate newEnd = Optional.ofNullable((String) payload.get("end_date")).map(LocalDate::parse).orElse(null);
        if (newStart != null && newEnd != null && newEnd.isBefore(newStart)) {
            return ResponseEntity.badRequest().body("结束日期不能早于开始日期");
        }
        ap.setStartDate(newStart);
        ap.setEndDate(newEnd);
        if (newStart != null) ap.setYear(newStart.getYear());
        ap.setDescription((String) payload.getOrDefault("description", null));
        ap.setStatus("PENDING");
        positionRepository.save(ap);
        return ResponseEntity.ok(Map.of("id", ap.getId()));
    }

	@PutMapping("/api/academic-positions/{id}")
	@Transactional
	public ResponseEntity<?> updatePosition(@PathVariable("id") Long id, @RequestBody Map<String, Object> payload) {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        AcademicPosition ap = positionRepository.findById(id).orElse(null);
        if (ap == null) return ResponseEntity.notFound().build();
        if (!currentIsAdmin() && !Objects.equals(ap.getUser().getId(), u.getId())) return ResponseEntity.status(403).body("无权编辑");
        ap.setPositionCategory((String) payload.get("position_category"));
        ap.setPositionTitle((String) payload.get("position_title"));
        ap.setOrganizationName((String) payload.get("organization_name"));
        ap.setLevel((String) payload.getOrDefault("level", null));
        ap.setYear(payload.get("year") == null ? null : Integer.valueOf(String.valueOf(payload.get("year"))));
        LocalDate newStart = Optional.ofNullable((String) payload.get("start_date")).map(LocalDate::parse).orElse(null);
        LocalDate newEnd = Optional.ofNullable((String) payload.get("end_date")).map(LocalDate::parse).orElse(null);
        if (newStart != null && newEnd != null && newEnd.isBefore(newStart)) {
            return ResponseEntity.badRequest().body("结束日期不能早于开始日期");
        }
        ap.setStartDate(newStart);
        ap.setEndDate(newEnd);
        if (newStart != null) ap.setYear(newStart.getYear());
        ap.setDescription((String) payload.getOrDefault("description", null));
        if (!currentIsAdmin()) {
            ap.setStatus("PENDING");
            ap.setReviewOpinion(null);
            ap.setReviewerId(null);
            ap.setReviewTime(null);
        }
        positionRepository.save(ap);
        return ResponseEntity.ok().build();
    }

	@DeleteMapping("/api/academic-positions/{id}")
	@Transactional
	public ResponseEntity<?> deletePosition(@PathVariable("id") Long id) {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        AcademicPosition ap = positionRepository.findById(id).orElse(null);
        if (ap == null) return ResponseEntity.notFound().build();
        if (!currentIsAdmin() && !Objects.equals(ap.getUser().getId(), u.getId())) return ResponseEntity.status(403).body("无权删除");
        positionRepository.deleteById(id);
        attachmentRepository.deleteByRelatedIdAndRelatedType(id, "academic_position");
        return ResponseEntity.ok().build();
    }

    @GetMapping("/api/academic-positions/all")
    public ResponseEntity<?> listAllPositions(@RequestParam(value = "category", required = false) String category,
                                              @RequestParam(value = "level", required = false) String level,
                                              @RequestParam(value = "year", required = false) Integer year,
                                              @RequestParam(value = "status", required = false) String status,
                                              @RequestParam(value = "page", required = false) Integer page,
                                              @RequestParam(value = "size", required = false) Integer size) {
        if (!currentIsAdmin()) return ResponseEntity.status(403).body("权限不足");
        List<AcademicPosition> list = positionRepository.findAllWithUser();
        List<Map<String, Object>> filtered = list.stream().filter(p -> {
            if (category != null && !category.isEmpty() && !category.equals(p.getPositionCategory())) return false;
            if (level != null && !level.isEmpty() && !level.equals(p.getLevel())) return false;
            if (year != null && !year.equals(p.getYear())) return false;
            if (status != null && !status.isEmpty() && !status.equals(p.getStatus())) return false;
            return true;
        }).map(p -> {
            Map<String, Object> m = new LinkedHashMap<>();
            m.put("id", p.getId());
            m.put("userId", p.getUser() != null ? p.getUser().getId() : null);
            m.put("userName", p.getUser() != null ? p.getUser().getName() : null);
            m.put("positionCategory", p.getPositionCategory());
            m.put("positionTitle", p.getPositionTitle());
            m.put("organizationName", p.getOrganizationName());
            m.put("level", p.getLevel());
            m.put("year", p.getYear());
            m.put("startDate", p.getStartDate());
            m.put("endDate", p.getEndDate());
            m.put("status", p.getStatus());
            return m;
        }).collect(Collectors.toList());
        int total = filtered.size();
        List<Map<String, Object>> pageList = applyPaging(filtered, page, size);
        if (page == null || size == null) {
            return ResponseEntity.ok(filtered);
        } else {
            return ResponseEntity.ok(Map.of("total", total, "list", pageList));
        }
    }

    @GetMapping("/api/academic-positions/pending")
    public ResponseEntity<?> listPendingPositions(@RequestParam(value = "category", required = false) String category,
                                                  @RequestParam(value = "level", required = false) String level,
                                                  @RequestParam(value = "year", required = false) Integer year,
                                                  @RequestParam(value = "page", required = false) Integer page,
                                                  @RequestParam(value = "size", required = false) Integer size) {
        return listAllPositions(category, level, year, "PENDING", page, size);
    }

	@PostMapping("/api/academic-positions/{id}/review")
	@Transactional
	public ResponseEntity<?> reviewPosition(@PathVariable("id") Long id, @RequestBody Map<String, Object> payload) {
        if (!currentIsAdmin()) return ResponseEntity.status(403).body("权限不足");
        String action = String.valueOf(payload.get("action"));
        String opinion = (String) payload.getOrDefault("opinion", null);
        AcademicPosition ap = positionRepository.findById(id).orElse(null);
        if (ap == null) return ResponseEntity.notFound().build();
        ap.setStatus("APPROVED".equalsIgnoreCase(action) ? "APPROVED" : "REJECTED");
        ap.setReviewOpinion(opinion);
        ap.setReviewerId(Optional.ofNullable(currentUser()).map(User::getId).orElse(null));
        ap.setReviewTime(LocalDateTime.now());
        positionRepository.save(ap);
        return ResponseEntity.ok().build();
    }

	@PostMapping("/api/academic-positions/{id}/attachments")
	@Transactional
	public ResponseEntity<?> uploadPositionAttachment(@PathVariable("id") Long id,
                                                      @RequestPart("file") MultipartFile file,
                                                      @RequestPart(value = "fileType", required = false) String fileType) throws Exception {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        AcademicPosition ap = positionRepository.findById(id).orElse(null);
        if (ap == null) return ResponseEntity.notFound().build();
        File dir = ensureDir(academicUploadDir);
        String original = Objects.requireNonNull(file.getOriginalFilename());
        String ext = original.contains(".") ? original.substring(original.lastIndexOf('.')) : "";
        String save = System.currentTimeMillis() + "_" + UUID.randomUUID() + ext;
        file.transferTo(new File(dir, save));
        Attachment att = new Attachment();
        att.setFileName(original);
        att.setFileUrl(dir.getPath() + File.separator + save);
        att.setRelatedType("academic_position");
        att.setRelatedId(id);
        att.setUploadedBy(u.getId());
        att.setUploadedAt(new Date());
        attachmentRepository.save(att);
        return ResponseEntity.ok(Map.of("url", att.getFileUrl()));
    }

    @GetMapping("/api/academic-positions/{id}/attachments")
    public List<Attachment> listPositionAttachments(@PathVariable("id") Long id) {
        return attachmentRepository.findByRelatedTypeAndRelatedId("academic_position", id);
    }

	@DeleteMapping("/api/academic-positions/{id}/attachments/{attId}")
	@Transactional
	public ResponseEntity<?> deletePositionAttachment(@PathVariable("id") Long id, @PathVariable("attId") Long attId) {
        attachmentRepository.deleteById(attId);
        return ResponseEntity.ok().build();
    }

    @GetMapping("/api/academic-positions/{id}/attachments/{attId}/download")
    public ResponseEntity<Resource> downloadPositionAttachment(@PathVariable("id") Long id, @PathVariable("attId") Long attId) {
        Attachment att = attachmentRepository.findById(attId).orElse(null);
        if (att == null || !Objects.equals(att.getRelatedId(), id) || !"academic_position".equals(att.getRelatedType())) {
            return ResponseEntity.notFound().build();
        }
        File file = new File(att.getFileUrl());
        if (!file.exists()) return ResponseEntity.notFound().build();
        String encodedName = java.net.URLEncoder.encode(att.getFileName(), StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedName)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(new FileSystemResource(file));
    }

    @GetMapping("/api/academic-positions/stats")
    public ResponseEntity<?> positionStats(@RequestParam(value = "category", required = false) String category,
                                           @RequestParam(value = "level", required = false) String level,
                                           @RequestParam(value = "year", required = false) Integer year,
                                           @RequestParam(value = "teacherId", required = false) Long teacherId) {
        if (!currentIsAdmin()) return ResponseEntity.status(403).body("权限不足");
        List<AcademicPosition> list = positionRepository.findAllWithUser();
        List<AcademicPosition> filtered = list.stream().filter(p -> {
            if (teacherId != null && (p.getUser() == null || !teacherId.equals(p.getUser().getId()))) return false;
            if (category != null && !category.isEmpty() && !category.equals(p.getPositionCategory())) return false;
            if (level != null && !level.isEmpty() && !level.equals(p.getLevel())) return false;
            if (year != null && !year.equals(p.getYear())) return false;
            return true;
        }).toList();
        Map<String, Long> byCategory = filtered.stream().collect(Collectors.groupingBy(AcademicPosition::getPositionCategory, Collectors.counting()));
        Map<String, Long> byLevel = filtered.stream().collect(Collectors.groupingBy(p -> Optional.ofNullable(p.getLevel()).orElse(""), Collectors.counting()));
        Map<Integer, Long> byYear = filtered.stream().collect(Collectors.groupingBy(p -> Optional.ofNullable(p.getYear()).orElse(-1), Collectors.counting()));
        Map<String, Long> byTeacher = filtered.stream().collect(Collectors.groupingBy(p -> p.getUser() != null ? Optional.ofNullable(p.getUser().getName()).orElse(String.valueOf(p.getUser().getId())) : "", Collectors.counting()));
        return ResponseEntity.ok(Map.of(
                "total", filtered.size(),
                "byCategory", byCategory,
                "byLevel", byLevel,
                "byYear", byYear,
                "byTeacher", byTeacher
        ));
    }

    /* =================== 社会服务 =================== */

	@GetMapping("/api/social-services/mine")
	@Transactional(readOnly = true)
	public ResponseEntity<?> myServices() {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        List<SocialService> list = serviceRepository.findByUser(u);
        return ResponseEntity.ok(list.stream().map(s -> {
            Map<String, Object> m = new LinkedHashMap<>();
            m.put("id", s.getId());
            m.put("serviceType", s.getServiceType());
            m.put("title", s.getTitle());
            m.put("content", s.getContent());
            m.put("organizationName", s.getOrganizationName());
            m.put("level", s.getLevel());
            m.put("year", s.getYear());
            m.put("startDate", s.getStartDate());
            m.put("endDate", s.getEndDate());
            m.put("status", s.getStatus());
            return m;
        }).toList());
    }

	@PostMapping("/api/social-services")
	@Transactional
	public ResponseEntity<?> createService(@RequestBody Map<String, Object> payload) {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        SocialService s = new SocialService();
        s.setUser(u);
        s.setServiceType((String) payload.get("service_type"));
        s.setTitle((String) payload.get("title"));
        s.setContent((String) payload.getOrDefault("content", null));
        s.setOrganizationName((String) payload.get("organization_name"));
        s.setLevel((String) payload.getOrDefault("level", null));
        s.setYear(payload.get("year") == null ? null : Integer.valueOf(String.valueOf(payload.get("year"))));
        LocalDate sStart = Optional.ofNullable((String) payload.get("start_date")).map(LocalDate::parse).orElse(null);
        LocalDate sEnd = Optional.ofNullable((String) payload.get("end_date")).map(LocalDate::parse).orElse(null);
        if (sStart != null && sEnd != null && sEnd.isBefore(sStart)) {
            return ResponseEntity.badRequest().body("结束日期不能早于开始日期");
        }
        s.setStartDate(sStart);
        s.setEndDate(sEnd);
        if (sStart != null) s.setYear(sStart.getYear());
        s.setStatus("PENDING");
        serviceRepository.save(s);
        return ResponseEntity.ok(Map.of("id", s.getId()));
    }

	@PutMapping("/api/social-services/{id}")
	@Transactional
	public ResponseEntity<?> updateService(@PathVariable("id") Long id, @RequestBody Map<String, Object> payload) {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        SocialService s = serviceRepository.findById(id).orElse(null);
        if (s == null) return ResponseEntity.notFound().build();
        if (!currentIsAdmin() && !Objects.equals(s.getUser().getId(), u.getId())) return ResponseEntity.status(403).body("无权编辑");
        s.setServiceType((String) payload.get("service_type"));
        s.setTitle((String) payload.get("title"));
        s.setContent((String) payload.getOrDefault("content", null));
        s.setOrganizationName((String) payload.get("organization_name"));
        s.setLevel((String) payload.getOrDefault("level", null));
        s.setYear(payload.get("year") == null ? null : Integer.valueOf(String.valueOf(payload.get("year"))));
        LocalDate sStart = Optional.ofNullable((String) payload.get("start_date")).map(LocalDate::parse).orElse(null);
        LocalDate sEnd = Optional.ofNullable((String) payload.get("end_date")).map(LocalDate::parse).orElse(null);
        if (sStart != null && sEnd != null && sEnd.isBefore(sStart)) {
            return ResponseEntity.badRequest().body("结束日期不能早于开始日期");
        }
        s.setStartDate(sStart);
        s.setEndDate(sEnd);
        if (sStart != null) s.setYear(sStart.getYear());
        if (!currentIsAdmin()) {
            s.setStatus("PENDING");
            s.setReviewOpinion(null);
            s.setReviewerId(null);
            s.setReviewTime(null);
        }
        serviceRepository.save(s);
        return ResponseEntity.ok().build();
    }

	@DeleteMapping("/api/social-services/{id}")
	@Transactional
	public ResponseEntity<?> deleteService(@PathVariable("id") Long id) {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        SocialService s = serviceRepository.findById(id).orElse(null);
        if (s == null) return ResponseEntity.notFound().build();
        if (!currentIsAdmin() && !Objects.equals(s.getUser().getId(), u.getId())) return ResponseEntity.status(403).body("无权删除");
        serviceRepository.deleteById(id);
        attachmentRepository.deleteByRelatedIdAndRelatedType(id, "social_service");
        return ResponseEntity.ok().build();
    }

    @GetMapping("/api/social-services/all")
    public ResponseEntity<?> listAllServices(@RequestParam(value = "type", required = false) String type,
                                             @RequestParam(value = "level", required = false) String level,
                                             @RequestParam(value = "year", required = false) Integer year,
                                             @RequestParam(value = "status", required = false) String status,
                                             @RequestParam(value = "page", required = false) Integer page,
                                             @RequestParam(value = "size", required = false) Integer size) {
        if (!currentIsAdmin()) return ResponseEntity.status(403).body("权限不足");
        List<SocialService> list = serviceRepository.findAllWithUser();
        List<Map<String, Object>> filtered = list.stream().filter(p -> {
            if (type != null && !type.isEmpty() && !type.equals(p.getServiceType())) return false;
            if (level != null && !level.isEmpty() && !level.equals(p.getLevel())) return false;
            if (year != null && !year.equals(p.getYear())) return false;
            if (status != null && !status.isEmpty() && !status.equals(p.getStatus())) return false;
            return true;
        }).map(s -> {
            Map<String, Object> m = new LinkedHashMap<>();
            m.put("id", s.getId());
            m.put("userId", s.getUser() != null ? s.getUser().getId() : null);
            m.put("userName", s.getUser() != null ? s.getUser().getName() : null);
            m.put("serviceType", s.getServiceType());
            m.put("title", s.getTitle());
            m.put("organizationName", s.getOrganizationName());
            m.put("level", s.getLevel());
            m.put("year", s.getYear());
            m.put("startDate", s.getStartDate());
            m.put("endDate", s.getEndDate());
            m.put("status", s.getStatus());
            return m;
        }).collect(Collectors.toList());
        int total = filtered.size();
        List<Map<String, Object>> pageList = applyPaging(filtered, page, size);
        if (page == null || size == null) {
            return ResponseEntity.ok(filtered);
        } else {
            return ResponseEntity.ok(Map.of("total", total, "list", pageList));
        }
    }

    @GetMapping("/api/social-services/pending")
    public ResponseEntity<?> listPendingServices(@RequestParam(value = "type", required = false) String type,
                                                 @RequestParam(value = "level", required = false) String level,
                                                 @RequestParam(value = "year", required = false) Integer year,
                                                 @RequestParam(value = "page", required = false) Integer page,
                                                 @RequestParam(value = "size", required = false) Integer size) {
        return listAllServices(type, level, year, "PENDING", page, size);
    }

	@PostMapping("/api/social-services/{id}/review")
	@Transactional
	public ResponseEntity<?> reviewService(@PathVariable("id") Long id, @RequestBody Map<String, Object> payload) {
        if (!currentIsAdmin()) return ResponseEntity.status(403).body("权限不足");
        String action = String.valueOf(payload.get("action"));
        String opinion = (String) payload.getOrDefault("opinion", null);
        SocialService s = serviceRepository.findById(id).orElse(null);
        if (s == null) return ResponseEntity.notFound().build();
        s.setStatus("APPROVED".equalsIgnoreCase(action) ? "APPROVED" : "REJECTED");
        s.setReviewOpinion(opinion);
        s.setReviewerId(Optional.ofNullable(currentUser()).map(User::getId).orElse(null));
        s.setReviewTime(LocalDateTime.now());
        serviceRepository.save(s);
        return ResponseEntity.ok().build();
    }

	@PostMapping("/api/social-services/{id}/attachments")
	@Transactional
	public ResponseEntity<?> uploadServiceAttachment(@PathVariable("id") Long id,
                                                     @RequestPart("file") MultipartFile file,
                                                     @RequestPart(value = "fileType", required = false) String fileType) throws Exception {
        User u = currentUser();
        if (u == null) return ResponseEntity.status(401).body("未登录");
        SocialService s = serviceRepository.findById(id).orElse(null);
        if (s == null) return ResponseEntity.notFound().build();
        File dir = ensureDir(academicUploadDir);
        String original = Objects.requireNonNull(file.getOriginalFilename());
        String ext = original.contains(".") ? original.substring(original.lastIndexOf('.')) : "";
        String save = System.currentTimeMillis() + "_" + UUID.randomUUID() + ext;
        file.transferTo(new File(dir, save));
        Attachment att = new Attachment();
        att.setFileName(original);
        att.setFileUrl(dir.getPath() + File.separator + save);
        att.setRelatedType("social_service");
        att.setRelatedId(id);
        att.setUploadedBy(u.getId());
        att.setUploadedAt(new Date());
        attachmentRepository.save(att);
        return ResponseEntity.ok(Map.of("url", att.getFileUrl()));
    }

    @GetMapping("/api/social-services/{id}/attachments")
    public List<Attachment> listServiceAttachments(@PathVariable("id") Long id) {
        return attachmentRepository.findByRelatedTypeAndRelatedId("social_service", id);
    }

	@DeleteMapping("/api/social-services/{id}/attachments/{attId}")
	@Transactional
	public ResponseEntity<?> deleteServiceAttachment(@PathVariable("id") Long id, @PathVariable("attId") Long attId) {
        attachmentRepository.deleteById(attId);
        return ResponseEntity.ok().build();
    }

    @GetMapping("/api/social-services/{id}/attachments/{attId}/download")
    public ResponseEntity<Resource> downloadServiceAttachment(@PathVariable("id") Long id, @PathVariable("attId") Long attId) {
        Attachment att = attachmentRepository.findById(attId).orElse(null);
        if (att == null || !Objects.equals(att.getRelatedId(), id) || !"social_service".equals(att.getRelatedType())) {
            return ResponseEntity.notFound().build();
        }
        File file = new File(att.getFileUrl());
        if (!file.exists()) return ResponseEntity.notFound().build();
        String encodedName = java.net.URLEncoder.encode(att.getFileName(), StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedName)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(new FileSystemResource(file));
    }

    @GetMapping("/api/social-services/stats")
    public ResponseEntity<?> serviceStats(@RequestParam(value = "type", required = false) String type,
                                          @RequestParam(value = "level", required = false) String level,
                                          @RequestParam(value = "year", required = false) Integer year,
                                          @RequestParam(value = "teacherId", required = false) Long teacherId) {
        if (!currentIsAdmin()) return ResponseEntity.status(403).body("权限不足");
        List<SocialService> list = serviceRepository.findAllWithUser();
        List<SocialService> filtered = list.stream().filter(p -> {
            if (teacherId != null && (p.getUser() == null || !teacherId.equals(p.getUser().getId()))) return false;
            if (type != null && !type.isEmpty() && !type.equals(p.getServiceType())) return false;
            if (level != null && !level.isEmpty() && !level.equals(p.getLevel())) return false;
            if (year != null && !year.equals(p.getYear())) return false;
            return true;
        }).toList();
        Map<String, Long> byType = filtered.stream().collect(Collectors.groupingBy(SocialService::getServiceType, Collectors.counting()));
        Map<String, Long> byLevel = filtered.stream().collect(Collectors.groupingBy(s -> Optional.ofNullable(s.getLevel()).orElse(""), Collectors.counting()));
        Map<Integer, Long> byYear = filtered.stream().collect(Collectors.groupingBy(s -> Optional.ofNullable(s.getYear()).orElse(-1), Collectors.counting()));
        Map<String, Long> byTeacher = filtered.stream().collect(Collectors.groupingBy(s -> s.getUser() != null ? Optional.ofNullable(s.getUser().getName()).orElse(String.valueOf(s.getUser().getId())) : "", Collectors.counting()));
        return ResponseEntity.ok(Map.of(
                "total", filtered.size(),
                "byType", byType,
                "byLevel", byLevel,
                "byYear", byYear,
                "byTeacher", byTeacher
        ));
    }
} 